package com.zhiyou.utils;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

public class RedisCache implements Cache {
	// 定义一个ID
	private final String id;
	// 创建读写锁对象
	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	// 获得jedis连接
	private static JedisConnectionFactory jedisConnectionFactory;

	// 为类中注入JedisConnectionFactory
	public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
		RedisCache.jedisConnectionFactory = jedisConnectionFactory;
	}

	// 通过构造方法给id赋值
	public RedisCache(String id) {
		this.id = id;
	}

	// 这个id实际上就是缓存的key
	public String getId() {
		return id;
	}

	// 将数据写入到缓存(redis)中
	public void putObject(Object key, Object value) {
		readWriteLock.writeLock().lock(); // 写数据的时候加入锁，防止自己写的时候别人也写
		// 获取到redis连接
		RedisConnection redisConnection = jedisConnectionFactory.getConnection();
		// 用于序列化数据(key,value)
		RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
		// 将key与value序列化
		redisConnection.set(serializer.serialize(key), serializer.serialize(value));
		System.out.println("*********************添加二级缓存成功,key:" + key + " value:" + value);
		// 关闭连接
		redisConnection.close();
		// 写入完成，释放锁
		readWriteLock.writeLock().unlock();
	}

	// 从缓存中取出数据
	public Object getObject(Object key) {
		readWriteLock.readLock().lock();// 读锁
		// 获取到redis连接
		RedisConnection redisConnection = jedisConnectionFactory.getConnection();
		// 用于序列化数据(key,value)
		RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
		// 先把key序列化，然后根据序列化后的key从redis取值，然后把取出的值进行反序列化
		Object object = serializer.deserialize(redisConnection.get(serializer.serialize(key)));
		System.out.println("------------------------命中二级缓存,value:" + object);
		// 关闭连接
		redisConnection.close();
		// 写入完成，放开锁
		readWriteLock.readLock().unlock();
		// 将redis中取出的数据放回
		return object;
	}

	// 从缓存中删除数据
	public Object removeObject(Object key) {
		readWriteLock.writeLock().lock();// 读锁
		// 获取到redis连接
		RedisConnection redisConnection = jedisConnectionFactory.getConnection();
		// 用于序列化数据(key,value)
		RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
		// 根据序列化后的key，将redis中对应的key生命周期设置为0
		Boolean expire = redisConnection.expire(serializer.serialize(key), 0);
		// 关闭连接
		redisConnection.close();
		// 写入完成，放开锁
		readWriteLock.writeLock().unlock();
		// 将redis中取出的数据放回
		return expire;
	}

	// 清空缓存
	public void clear() {
		readWriteLock.readLock().lock();// 读锁
		// 获取到redis连接
		RedisConnection redisConnection = jedisConnectionFactory.getConnection();
		// 刷新
		redisConnection.flushDb();
		redisConnection.flushAll();
		redisConnection.close();
		readWriteLock.readLock().unlock();
	}

	// 获得缓存中数据量
	public int getSize() {
		// 获取到redis连接
		RedisConnection redisConnection = jedisConnectionFactory.getConnection();
		Integer size = Integer.valueOf(redisConnection.dbSize().toString());
		redisConnection.close();
		return size;
	}

	//
	public ReadWriteLock getReadWriteLock() {
		return readWriteLock;
	}

}
